#include <stdio.h>
#include <stdlib.h>

//1d array
void demo1(){
    int *p = (int *) malloc( sizeof(int)*2 );

    for(int i=0; i<2; i++){
        *(p+1) = i+99;
        printf("arr[%d]=%d\n", i, *(p+1));
    }
}

//2d array
void demo2(){
    // p[3][4]
    int **p=(int **)malloc( sizeof(int*)*3 ); //声明一个长度3的数组，其内容都是指针，指向int
    for(int i=0; i<3; i++){
        p[i]=(int*) malloc( sizeof(int)*4 ); //每个指针也指向一个长度为4的int数组
    }
    //指针大小: 8; int 大小: 4
    printf("size of p: %ld; p[0][0]=%ld\n", sizeof(p), sizeof(p[0][0]) );

    // 初始化
    for(int i=0; i<3; i++){
        for(int j=0; j<4; j++){
            *(*(p+i) +j )=100 + i+j + i*j; //二维数组 使用 指针形式
            printf("%p [%d][%d]=%d\t", &p[i][j], i, j, p[i][j]); //二维数组 使用 数组形式
        }
        printf("\n");
    }

    // 看看一级指针的坐标，就是二级数组的第一个元素
    printf("\n");
    for(int i=0; i<3; i++){
        printf("%p [%d];  %p [%d][0] \n", p[i], i, &p[i][0],i );
    }

    //释放内存: 逐层释放，子内存释放完才能释放父内存
    printf("before free: %p, [0][0]=%d\n", p, p[0][0]);
    for(int i=0; i<3; i++){
        printf("free p[%d]\n", i);
        free(p[i]);
    }
    free(p); //释放一级指针数组
    //printf("after free: %p, [0][0]=%d\n", p, p[0][0]);
}

//3d array
// 内存要逐级释放
void demo3(){
    int X=3, Y=2, Z=5;
    // 分配空间
    int ***p = malloc(sizeof(int**) * X);
    for (int i = 0; i < X; i++) {
        p[i] = malloc(sizeof(int*) * Y); // 分配空间
        for (int j = 0; j < Y; j++) {
            p[i][j] = malloc(sizeof(int) * Z); // 分配空间
            // 能直接赋值吗？
            for(int k=0; k<Z; k++){
                p[i][j][k]=i+j+k + i*j*k;
                printf("%p [%d][%d][%d]=%d\t", &p[i][j][k], i, j, k, p[i][j][k]);
            }
            printf("\n");
        }
        printf("\n");
    }

    // 释放时从最深层开始
    for (int i = 0; i < X; i++) {
        for (int j = 0; j < Y; j++) {
            free(p[i][j]);
        }
        free(p[i]);
    }
    free(p);
}

int main(){
    //demo1();
    //demo2(); // 2d array
    demo3(); //3d array
    printf("\n");

    return 0;
}
